package com.lancoo.dictionary.data.adapter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.lancoo.dictionary.DictionaryHelper;
import com.lancoo.dictionary.R;
import com.lancoo.dictionary.data.model.Meaning;
import com.lancoo.dictionary.data.model.Paraphrase;
import com.lancoo.dictionary.data.model.SampleSentence;
import com.lancoo.dictionary.data.model.SampleUsage;
import com.lancoo.dictionary.data.model.UsageExample;
import com.lancoo.dictionary.data.model.Vocabulary;
import com.lancoo.dictionary.utils.DitchItemDecoration;
import com.lancoo.dictionary.utils.XBaseViewHolder;

import android.media.MediaPlayer;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.Adapter;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.Html;
import android.text.TextUtils;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class SearchResultAdapter extends Adapter<ViewHolder> implements OnCheckedChangeListener {
	static final int VIEWTYPE_HEAD = 0;
	static final int VIEWTYPE_SAMPLE_SENTENCE = 1;
	static final int VIEWTYPE_COMMON_USAGE = 2;
	static final int VIEWTYPE_CLASSIAL_USAGE = 3;
	static final int VIEWTYPE_RELATIVE_KNOWLEDGE = 4;
	static final int VIEWTYPE_E_E = 5;
	static final int VIEWTYPE_BAIKE = 6;

	private Vocabulary vocabulary;
	private List<DataWrapper> dataList;
	private MediaPlayer mediaPlayer;
	private boolean allExpanded;
	private boolean allCollapsed;
	private SparseBooleanArray expandState = new SparseBooleanArray();

	public SearchResultAdapter(Vocabulary vocabulary, MediaPlayer mediaPlayer) {
		this.vocabulary = vocabulary;
		this.mediaPlayer = mediaPlayer;
		unpackData();
	}

	class DataWrapper {
		int dataType;
		Object data;

		public DataWrapper(int dataType, Object data) {
			this.dataType = dataType;
			this.data = data;
		}

	}

	/**
	 * 
	 * 使用如此多的ViewHolder应对各子视图需求变更
	 */
	static class HeadViewHolder extends XBaseViewHolder {

		private TextView searchKnowlegde;
		private TextView britishPronunciation;
		private TextView americanPronunciation;
		private TextView chineseMeaning;
		private RadioGroup rgAllExpandCollapse;

		public HeadViewHolder(View itemView) {
			super(itemView);
			searchKnowlegde = (TextView) itemView.findViewById(R.id.item_search_knowlegde);
			britishPronunciation = (TextView) itemView.findViewById(R.id.item_british_pronunciation);
			americanPronunciation = (TextView) itemView.findViewById(R.id.item_american_pronunciation);
			chineseMeaning = (TextView) itemView.findViewById(R.id.item_chinese_meaning);
			rgAllExpandCollapse = (RadioGroup) itemView.findViewById(R.id.item_all_expand_collapse);
		}
	}

	static class SentenceViewHolder extends XBaseViewHolder {

		private RecyclerView sentenceRv;
		private LinearLayout expandableLinearLayout;
		private ImageButton itemExpandCollapse;
		private RelativeLayout rlExpandCollapse;
		private TextView itemLabel;

		public SentenceViewHolder(View itemView) {
			super(itemView);
			sentenceRv = (RecyclerView) itemView.findViewById(R.id.item_sentence_rv);
			sentenceRv.addItemDecoration(new DitchItemDecoration(6f));
			expandableLinearLayout = (LinearLayout) itemView.findViewById(R.id.item_sentence_ell);
			itemExpandCollapse = (ImageButton) itemView.findViewById(R.id.item_expand_collapse);
			rlExpandCollapse = (RelativeLayout) itemView.findViewById(R.id.rl_expand_collapse);
			itemLabel = (TextView) itemView.findViewById(R.id.item_label);
		}
	}

	static class CommonViewHolder extends XBaseViewHolder {

		private RecyclerView commonRv;
		private LinearLayout expandableLinearLayout;
		private ImageButton itemExpandCollapse;
		private RelativeLayout rlExpandCollapse;
		private TextView itemLabel;

		public CommonViewHolder(View itemView) {
			super(itemView);
			commonRv = (RecyclerView) itemView.findViewById(R.id.item_common_rv);
			commonRv.addItemDecoration(new DitchItemDecoration(6f));
			expandableLinearLayout = (LinearLayout) itemView.findViewById(R.id.item_common_ell);
			itemExpandCollapse = (ImageButton) itemView.findViewById(R.id.item_expand_collapse);
			rlExpandCollapse = (RelativeLayout) itemView.findViewById(R.id.rl_expand_collapse);
			itemLabel = (TextView) itemView.findViewById(R.id.item_label);
		}
	}

	static class ClassicalViewHolder extends XBaseViewHolder {

		private TextView classicalUasge;
		private LinearLayout expandableLinearLayout;
		private ImageButton itemExpandCollapse;
		private RelativeLayout rlExpandCollapse;
		private TextView itemLabel;

		public ClassicalViewHolder(View itemView) {
			super(itemView);
			classicalUasge = (TextView) itemView.findViewById(R.id.item_classical_uasge);
			expandableLinearLayout = (LinearLayout) itemView.findViewById(R.id.item_classical_ell);
			itemExpandCollapse = (ImageButton) itemView.findViewById(R.id.item_expand_collapse);
			rlExpandCollapse = (RelativeLayout) itemView.findViewById(R.id.rl_expand_collapse);
			itemLabel = (TextView) itemView.findViewById(R.id.item_label);
		}
	}

	static class RelativeViewHolder extends XBaseViewHolder {

		private TextView relativeUasge;
		private LinearLayout expandableLinearLayout;
		private ImageButton itemExpandCollapse;
		private RelativeLayout rlExpandCollapse;
		private TextView itemLabel;

		public RelativeViewHolder(View itemView) {
			super(itemView);
			relativeUasge = (TextView) itemView.findViewById(R.id.item_relative_knowledge);
			expandableLinearLayout = (LinearLayout) itemView.findViewById(R.id.item_relative_ell);
			itemExpandCollapse = (ImageButton) itemView.findViewById(R.id.item_expand_collapse);
			rlExpandCollapse = (RelativeLayout) itemView.findViewById(R.id.rl_expand_collapse);
			itemLabel = (TextView) itemView.findViewById(R.id.item_label);
		}
	}

	static class EEViewHolder extends XBaseViewHolder {

		private TextView englishMeaning;
		private LinearLayout expandableLinearLayout;
		private ImageButton itemExpandCollapse;
		private RelativeLayout rlExpandCollapse;
		private TextView itemLabel;

		public EEViewHolder(View itemView) {
			super(itemView);
			englishMeaning = (TextView) itemView.findViewById(R.id.item_english_meaning);
			expandableLinearLayout = (LinearLayout) itemView.findViewById(R.id.item_ee_ell);
			itemExpandCollapse = (ImageButton) itemView.findViewById(R.id.item_expand_collapse);
			rlExpandCollapse = (RelativeLayout) itemView.findViewById(R.id.rl_expand_collapse);
			itemLabel = (TextView) itemView.findViewById(R.id.item_label);
		}
	}

	static class BaikeViewHolder extends XBaseViewHolder {

		private TextView baikeMeaning;
		private LinearLayout expandableLinearLayout;
		private ImageButton itemExpandCollapse;
		private RelativeLayout rlExpandCollapse;
		private TextView itemLabel;

		public BaikeViewHolder(View itemView) {
			super(itemView);
			baikeMeaning = (TextView) itemView.findViewById(R.id.item_baike_meaning);
			expandableLinearLayout = (LinearLayout) itemView.findViewById(R.id.item_baike_ell);
			itemExpandCollapse = (ImageButton) itemView.findViewById(R.id.item_expand_collapse);
			rlExpandCollapse = (RelativeLayout) itemView.findViewById(R.id.rl_expand_collapse);
			itemLabel = (TextView) itemView.findViewById(R.id.item_label);
		}
	}

	@Override
	public int getItemCount() {
		return dataList.size();
	}

	@Override
	public int getItemViewType(int position) {
		return dataList.get(position).dataType;
	}

	@Override
	public void onBindViewHolder(ViewHolder viewHolder, final int position) {
		if (viewHolder instanceof HeadViewHolder) {
			HeadViewHolder headViewHolder = (HeadViewHolder) viewHolder;
			headViewHolder.searchKnowlegde.setText(vocabulary.getCwName());
			CharSequence cMeaningStr = (CharSequence) dataList.get(position).data;
			headViewHolder.chineseMeaning.setText(cMeaningStr);
			String unPText = vocabulary.getUnPText();
			headViewHolder.britishPronunciation
					.setText((TextUtils.isEmpty(unPText) ? "无英式音标" : "英 " + Html.fromHtml(unPText)));
			headViewHolder.britishPronunciation.setOnClickListener(new PlaySoundsListener(vocabulary.getUnPVoice()));
			String usPText = vocabulary.getUsPText();
			headViewHolder.americanPronunciation
					.setText((TextUtils.isEmpty(usPText) ? "无美式音标" : "美 " + Html.fromHtml(usPText)));
			headViewHolder.americanPronunciation.setOnClickListener(new PlaySoundsListener(vocabulary.getUsPVoice()));

			headViewHolder.rgAllExpandCollapse.setOnCheckedChangeListener(null);
			if (!(allExpanded ^ allCollapsed)) {
				headViewHolder.rgAllExpandCollapse.clearCheck();
			} else {
				headViewHolder.rgAllExpandCollapse.check(allExpanded ? R.id.item_all_expand : R.id.item_all_collapse);
			}
			headViewHolder.rgAllExpandCollapse.setOnCheckedChangeListener(this);
		} else if (viewHolder instanceof SentenceViewHolder) {
			SentenceViewHolder sentenceViewHolder = (SentenceViewHolder) viewHolder;
			sentenceViewHolder.itemLabel.setText(R.string.lcdic_sample_sentence);
			List<Meaning> meanings = (List<Meaning>) dataList.get(position).data;
			sentenceViewHolder.sentenceRv.setAdapter(new SentenceAdapter(meanings, this));
			ExpandCollapseListener expandCollapseListener = new ExpandCollapseListener(
					sentenceViewHolder.expandableLinearLayout, position);
			sentenceViewHolder.rlExpandCollapse.setOnClickListener(expandCollapseListener);
			sentenceViewHolder.itemExpandCollapse.setOnClickListener(expandCollapseListener);
			updateViewExpandOrNot(sentenceViewHolder.expandableLinearLayout, position,
					sentenceViewHolder.itemExpandCollapse);

		} else if (viewHolder instanceof CommonViewHolder) {
			CommonViewHolder commonViewHolder = (CommonViewHolder) viewHolder;
			commonViewHolder.itemLabel.setText(R.string.lcdic_common_usage);
			List<SampleSentence> commonUsageSentences = (List<SampleSentence>) dataList.get(position).data;
			commonViewHolder.commonRv.setAdapter(new CommonUsageAdapter(commonUsageSentences, this));
			ExpandCollapseListener expandCollapseListener = new ExpandCollapseListener(
					commonViewHolder.expandableLinearLayout, position);
			commonViewHolder.rlExpandCollapse.setOnClickListener(expandCollapseListener);
			commonViewHolder.itemExpandCollapse.setOnClickListener(expandCollapseListener);
			updateViewExpandOrNot(commonViewHolder.expandableLinearLayout, position,
					commonViewHolder.itemExpandCollapse);

		} else if (viewHolder instanceof ClassicalViewHolder) {
			ClassicalViewHolder classicalViewHolder = (ClassicalViewHolder) viewHolder;
			classicalViewHolder.itemLabel.setText(R.string.lcdic_classical_usage);
			CharSequence eMeaningStr = (CharSequence) dataList.get(position).data;
			classicalViewHolder.classicalUasge.setText(eMeaningStr);
			ExpandCollapseListener expandCollapseListener = new ExpandCollapseListener(
					classicalViewHolder.expandableLinearLayout, position);
			classicalViewHolder.rlExpandCollapse.setOnClickListener(expandCollapseListener);
			classicalViewHolder.itemExpandCollapse.setOnClickListener(expandCollapseListener);
			updateViewExpandOrNot(classicalViewHolder.expandableLinearLayout, position,
					classicalViewHolder.itemExpandCollapse);
		} else if (viewHolder instanceof RelativeViewHolder) {
			RelativeViewHolder relativeViewHolder = (RelativeViewHolder) viewHolder;
			relativeViewHolder.itemLabel.setText(R.string.lcdic_relative_knowledge);
			CharSequence eMeaningStr = (CharSequence) dataList.get(position).data;
			relativeViewHolder.relativeUasge.setText(eMeaningStr);
			ExpandCollapseListener expandCollapseListener = new ExpandCollapseListener(
					relativeViewHolder.expandableLinearLayout, position);
			relativeViewHolder.rlExpandCollapse.setOnClickListener(expandCollapseListener);
			relativeViewHolder.itemExpandCollapse.setOnClickListener(expandCollapseListener);
			updateViewExpandOrNot(relativeViewHolder.expandableLinearLayout, position,
					relativeViewHolder.itemExpandCollapse);
		} else if (viewHolder instanceof EEViewHolder) {
			EEViewHolder eeViewHolder = (EEViewHolder) viewHolder;
			eeViewHolder.itemLabel.setText(R.string.lcdic_english_english_meaning);
			CharSequence eMeaningStr = (CharSequence) dataList.get(position).data;
			eeViewHolder.englishMeaning.setText(eMeaningStr);
			ExpandCollapseListener expandCollapseListener = new ExpandCollapseListener(
					eeViewHolder.expandableLinearLayout, position);
			eeViewHolder.rlExpandCollapse.setOnClickListener(expandCollapseListener);
			eeViewHolder.itemExpandCollapse.setOnClickListener(expandCollapseListener);
			updateViewExpandOrNot(eeViewHolder.expandableLinearLayout, position, eeViewHolder.itemExpandCollapse);
		} else if (viewHolder instanceof BaikeViewHolder) {
			BaikeViewHolder baikeViewHolder = (BaikeViewHolder) viewHolder;
			baikeViewHolder.itemLabel.setText(R.string.lcdic_baike_meaning);
			CharSequence baikeMeaningStr = (CharSequence) dataList.get(position).data;
			baikeViewHolder.baikeMeaning.setText(baikeMeaningStr);
			ExpandCollapseListener expandCollapseListener = new ExpandCollapseListener(
					baikeViewHolder.expandableLinearLayout, position);
			baikeViewHolder.rlExpandCollapse.setOnClickListener(expandCollapseListener);
			baikeViewHolder.itemExpandCollapse.setOnClickListener(expandCollapseListener);
			updateViewExpandOrNot(baikeViewHolder.expandableLinearLayout, position, baikeViewHolder.itemExpandCollapse);
		}
	}

	private void updateViewExpandOrNot(View targetView, int position, ImageButton indicator) {
		/**
		 * 全部展开/折叠有一项有效则以其为准，否则，以保存状态为准
		 */
		if (allExpanded ^ allCollapsed) {
			targetView.setVisibility(allExpanded ? View.VISIBLE : View.GONE);
		} else {
			targetView.setVisibility(expandState.get(position) ? View.VISIBLE : View.GONE);
		}
		indicator.setBackgroundResource(
				targetView.getVisibility() == View.VISIBLE ? R.drawable.lcdic_collapse : R.drawable.lcdic_expand);
	}

	private void initExpandState(boolean expanded) {
		for (int i = 0; i < dataList.size(); i++) {
			expandState.put(i, expanded);
		}
		allExpanded = expanded;
		allCollapsed = !expanded;
	}

	@Override
	public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
		switch (viewType) {
		case VIEWTYPE_HEAD:
			return new HeadViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_header, null));
		case VIEWTYPE_SAMPLE_SENTENCE:
			return new SentenceViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_sentence, null));
		case VIEWTYPE_COMMON_USAGE:
			return new CommonViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_common, null));
		case VIEWTYPE_CLASSIAL_USAGE:
			return new ClassicalViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_classical, null));
		case VIEWTYPE_RELATIVE_KNOWLEDGE:
			return new RelativeViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_relative, null));
		case VIEWTYPE_E_E:
			return new EEViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_ee, null));
		case VIEWTYPE_BAIKE:
			return new BaikeViewHolder(
					LayoutInflater.from(parent.getContext()).inflate(R.layout.lcdic_item_search_result_baike, null));
		default:
			return null;
		}
	}

	private void unpackData() {
		dataList = new ArrayList<>();
		List<Paraphrase> paraphrases = vocabulary.getCxCollection();
		// 英文释义
		StringBuilder eBuilder = new StringBuilder();
		// 中文释义
		StringBuilder cBuilder = new StringBuilder();
		// 经典应用
		StringBuilder classicalBuilder = new StringBuilder();
		// 相关词汇
		StringBuilder relativeBuilder = new StringBuilder();
		// 例句，临时
		List<Meaning> combineMeanings = new ArrayList<>();
		// 百科释义
		StringBuilder baikeBuilder = new StringBuilder();
		//if (paraphrases != null) {// 修复Bug By TML
			for (int i = 0; i < paraphrases.size(); i++) {
				Paraphrase paraphrase = paraphrases.get(i);
				String cp = paraphrase.getCxChinese();
				if (!TextUtils.isEmpty(cp)) {
					cBuilder.append(cp).append('。');
				}
				String ep = paraphrase.getCxEnglish();
				if (!TextUtils.isEmpty(ep)) {
					eBuilder.append(ep).append("<BR/>");
				}
				List<Meaning> meanings = paraphrase.getMeanCollection();
				if (meanings == null) {
					continue;
				}
				combineMeanings.addAll(meanings);
				for (int j = 0; j < meanings.size(); j++) {
					Meaning meaning = meanings.get(j);
					cBuilder.append(Html.fromHtml(meaning.getChineseMeaning()));
					eBuilder.append(meaning.getEnglishMeaning());
					if (j < meanings.size() - 1) {
						cBuilder.append('；');
						eBuilder.append("<BR/>");
					}
					List<SampleUsage> baikeUsages = meaning.getBaikeCollection();
					List<SampleUsage> classicalUsages = meaning.getClassicCollection();
					List<SampleUsage> relativeUsages = meaning.getRltCollection();
					if (baikeUsages != null) {
						for (SampleUsage baikeUsage : baikeUsages) {
							baikeBuilder.append(baikeUsage.getContent());
						}
					}
					if (classicalUsages != null) {
						for (SampleUsage classicalUsage : classicalUsages) {
							classicalBuilder.append(classicalUsage.getContent());
						}
					}
					if (relativeUsages != null) {
						for (SampleUsage relativeUsage : relativeUsages) {
							relativeBuilder.append(relativeUsage.getTitle()).append(relativeUsage.getContent());
						}
					}
				}
				if (i < paraphrases.size() - 1) {
					cBuilder.append('\n');
					eBuilder.append("<BR/>");
				}
			}
		//}
		dataList.add(new DataWrapper(VIEWTYPE_HEAD, cBuilder));
		if (combineMeanings.size() > 0) {
			dataList.add(new DataWrapper(VIEWTYPE_SAMPLE_SENTENCE, combineMeanings));
			List<SampleSentence> commonUsageSentences = new ArrayList<>();
			for (Meaning meaning : combineMeanings) {
				if (meaning != null) {
					List<UsageExample> usageExamples = meaning.getColtCollection();
					if (usageExamples != null) {
						for (UsageExample usageExample : usageExamples) {
							List<SampleSentence> tmp = usageExample.getSenCollection();
							if (tmp != null) {
								commonUsageSentences.addAll(tmp);
							}
						}
					}
				}
			}
			if (commonUsageSentences.size() > 0) {
				dataList.add(new DataWrapper(VIEWTYPE_COMMON_USAGE, commonUsageSentences));
			}
		}
		if (!TextUtils.isEmpty(classicalBuilder)) {
			dataList.add(new DataWrapper(VIEWTYPE_CLASSIAL_USAGE, Html.fromHtml(classicalBuilder.toString())));
		}
		if (!TextUtils.isEmpty(relativeBuilder)) {
			dataList.add(new DataWrapper(VIEWTYPE_RELATIVE_KNOWLEDGE, Html.fromHtml(relativeBuilder.toString())));
		}
		if (!TextUtils.isEmpty(eBuilder)) {
			dataList.add(new DataWrapper(VIEWTYPE_E_E, Html.fromHtml(eBuilder.toString())));
		}
		if (!TextUtils.isEmpty(baikeBuilder)) {
			dataList.add(new DataWrapper(VIEWTYPE_BAIKE, Html.fromHtml(baikeBuilder.toString())));
		}
		initExpandState(true);
	}

	private void playSounds(String uri) {
		uri = DictionaryHelper.RES_BASE_URL + uri;
		mediaPlayer.reset();
		try {
			mediaPlayer.setDataSource(DictionaryHelper.uriEncode(uri));
			mediaPlayer.prepareAsync();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class PlaySoundsListener implements View.OnClickListener {
		private String uri;

		public PlaySoundsListener(String uri) {
			this.uri = uri;
		}

		@Override
		public void onClick(View v) {
			playSounds(uri);
		}
	}

	public void bindPlaySoundsListener(View targetView, String uri) {
		targetView.setOnClickListener(new PlaySoundsListener(uri));
	}

	class ExpandCollapseListener implements View.OnClickListener {

		private View targetView;
		private int position;

		public ExpandCollapseListener(View targetView, int position) {
			this.targetView = targetView;
			this.position = position;
		}

		@Override
		public void onClick(View v) {
			boolean expanded = targetView.getVisibility() == View.VISIBLE;
			if (expanded) {
				targetView.setVisibility(View.GONE);
				expandState.put(position, false);
				allExpanded = false;
			} else {
				targetView.setVisibility(View.VISIBLE);
				expandState.put(position, true);
				allCollapsed = false;
			}
			checkExpandState();
			SearchResultAdapter.this.notifyDataSetChanged();
		}

	}

	@Override
	public void onCheckedChanged(RadioGroup group, int checkedId) {
		if (checkedId == R.id.item_all_expand) {
			initExpandState(true);
			this.notifyDataSetChanged();
		} else if (checkedId == R.id.item_all_collapse) {
			initExpandState(false);
			this.notifyDataSetChanged();
		}
	}

	public void updateData(Vocabulary vocabulary) {
		this.vocabulary = vocabulary;
		unpackData();
		this.notifyDataSetChanged();
	}
	
	private void checkExpandState(){
		boolean tempState = false;
		for (int i = 1; i<dataList.size();i++) {
			boolean curState = expandState.get(i);
			if (i==1) {
				tempState = curState;
			}else{
				if (tempState!=curState) {
					return;
				}
			}
		}
		if (tempState) {
			allExpanded = true;
		}else{
			allCollapsed = true;
		}
	}

}
